//package cn.stylefeng.guns.modular.business.timer;
//
//import cn.hutool.core.date.DateUtil;
//import cn.stylefeng.guns.core.context.login.LoginContextHolder;
//import cn.stylefeng.guns.modular.business.app.mapper.BalancePaymentMapper;
//import cn.stylefeng.guns.modular.business.app.mapper.PayOrderMapper;
//import cn.stylefeng.guns.modular.business.app.pojo.BalancePayment;
//import cn.stylefeng.guns.modular.business.app.pojo.PayOrder;
//import cn.stylefeng.guns.modular.business.app.service.ApiPayService;
//import cn.stylefeng.guns.sys.modular.user.constant.ApiPayConstant;
//import cn.stylefeng.guns.sys.modular.user.entity.EnterpriseUserMsg;
//import cn.stylefeng.guns.sys.modular.user.entity.SysTenant;
//import cn.stylefeng.guns.sys.modular.user.mapper.EnterpriseUserMsgMapper;
//import cn.stylefeng.guns.sys.modular.user.service.SysTenantService;
//import cn.stylefeng.guns.sys.modular.user.utils.ApiPayUtil;
//import cn.stylefeng.guns.sys.modular.user.utils.param.AcctInfo;
//import cn.stylefeng.guns.sys.modular.user.utils.param.BalancePaymentParam;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.huifu.bspay.sdk.opps.core.utils.DateTools;
//import com.huifu.bspay.sdk.opps.core.utils.SequenceTools;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.time.LocalDateTime;
//import java.util.*;
//
//@Component
//@Slf4j
//public class DivideAccountsTimer {
//
//    @Autowired
//    private PayOrderMapper payOrderMapper;
//
//    @Autowired
//    private EnterpriseUserMsgMapper enterpriseUserMsgMapper;
//
//    @Autowired
//    private BalancePaymentMapper balancePaymentMapper;
//
//
//    /**
//     * 每天凌晨1点执行
//     */
//    //@Scheduled(cron = "*/5 * * * * ?")
////    @Scheduled(cron = "0 0 1 * * ?")
////    @Scheduled(cron = "0 */1 * * * ?")
//    public void handler() {
//        log.info("开始进行分账....");
//        //查询订单表中已经完成但是未分账的记录
//        List<PayOrder> orderList = payOrderMapper.selectList(new LambdaQueryWrapper<PayOrder>()
//                .eq(PayOrder::getStatus, 1)
//                .eq(PayOrder::getIsDivideAcc, 0)
////                        .eq(PayOrder::getTenantId,1758661209265299458L)
//                .lt(PayOrder::getCreateTime, DateUtil.beginOfDay(new Date())));
//
//        //对集合进行校验
//        if (Objects.isNull(orderList) || orderList.size() < 1) {
//            return;
//        }
//
//        //遍历集合计算每个租户的订单总额，并将订单状态修改为已分账
//        Map<Long, BigDecimal> map = countAndUpdate(orderList);
//        Map<Long, List<PayOrder>> payOrderMap = payOrderMap(orderList);
//
//        Iterator<Map.Entry<Long, BigDecimal>> iterator = map.entrySet().iterator();
//        while (iterator.hasNext()) {
//            Map.Entry<Long, BigDecimal> next = iterator.next();
//            Map<Long, BigDecimal> mapSingle = new HashMap<>();
//            mapSingle.put(next.getKey(), next.getValue());
//            divideAccounts(mapSingle, payOrderMap.get(next.getKey()));
//        }
//
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    public void divideAccounts(Map<Long, BigDecimal> mapSingle, List<PayOrder> payOrderList) {
//        //构建余额支付的参数对象
//        BalancePaymentParam param = getBalancePaymentParam(mapSingle);
//
//        //将余额支付信息入库
//        saveBalancePayMsgToDataBase(param);
//
//        //调用第三方接口完成余额支付
//        try {
//            doBalancePay(param);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//        payOrderList.stream().forEach(x -> {
//            x.setIsDivideAcc(1);
//            payOrderMapper.updateById(x);
//        });
//
//    }
//
//    /**
//     * 将余额支付信息入库
//     */
//    private void saveBalancePayMsgToDataBase(BalancePaymentParam param) {
//        //创建实体类对象
//        BalancePayment balancePayment = new BalancePayment();
//
//        //属性拷贝
//        BeanUtils.copyProperties(param, balancePayment);
//
//        //补充属性
//        balancePayment.setCreateTime(LocalDateTime.now());
//        balancePayment.setUpdateTime(LocalDateTime.now());
//
//        //暂时将交易状态设置为处理中
//        balancePayment.setStatus(0);
//
//        //获取分账对象
//        //balancePayment.setAcctSplitBunch(getAcctSplitBunch(param.getAcctInfos()));
//
//        //获取多个分账对象
//        List<AcctInfo> acctInfos = param.getAcctInfos();
//
//        //遍历集合
//        acctInfos.forEach(s -> {
//            balancePayment.setHuifuId(s.getHuifuId());
//
//            //根据汇付id查询租户id
//            EnterpriseUserMsg enterpriseUserMsg = enterpriseUserMsgMapper.selectOne(new LambdaQueryWrapper<EnterpriseUserMsg>()
//                    .eq(EnterpriseUserMsg::getHuifuId, s.getHuifuId()));
//            balancePayment.setTenantId(enterpriseUserMsg.getTenantId());
//
//            balancePayment.setDividendAmount(s.getDivAmt());
//
//            //插入数据库
//            balancePaymentMapper.insert(balancePayment);
//        });
//    }
//
//    /**
//     * 调用第三方接口完成余额支付
//     */
//    private void doBalancePay(BalancePaymentParam param) throws Exception {
//        //调用第三方接口
//        Map<String, Object> map = ApiPayUtil.balancePay(param);
//        //如果交易状态不成功直接抛出异常让数据库回滚
//        if (!"S".equals(map.get("trans_stat"))) {
//            throw new RuntimeException((String) map.get("resp_desc"));
//        }
//
//        //如果交易成功，修改数据库状态
//        List<BalancePayment> balancePaymentList = balancePaymentMapper.selectList(new LambdaQueryWrapper<BalancePayment>()
//                .eq(BalancePayment::getReqDate, param.getReqDate())
//                .eq(BalancePayment::getReqSeqId, param.getReqSeqId()));
//
//        //遍历集合
//        balancePaymentList.forEach(s -> {
//            s.setStatus(1);
//            balancePaymentMapper.updateById(s);
//        });
//
//    }
//
//    @Autowired
//    private SysTenantService sysTenantService;
//
//    public String getHuifuId(Long tenantId) {
//        SysTenant sysTenant = sysTenantService.getById(tenantId);
//        if (sysTenant == null) {
//            return null;
//        }
//        return sysTenant.getHuifuId();
//    }
//
//
//    /**
//     * 构建余额支付的参数对象
//     */
//    private BalancePaymentParam getBalancePaymentParam(Map<Long, BigDecimal> map) {
//        //创建BalancePaymentParam对象
//        BalancePaymentParam param = new BalancePaymentParam();
//
//        //注入属性值
//        param.setReqDate(DateTools.getCurrentDateYYYYMMDD());
//        param.setReqSeqId(SequenceTools.getReqSeqId32());
//        param.setOutHuifuId(ApiPayConstant.HUI_FU_ID);
//
//        //根据租户id查询每个租户的手续费及租户对应的汇付id
//        Map<String, String> commissionMap = getCommissionMap(map);
//
//        //设置分账对象及支付金额
//        setParamValue(map, param, commissionMap);
//
//        return param;
//    }
//
//    /**
//     * 设置分账对象及支付金额
//     */
//    private void setParamValue(Map<Long, BigDecimal> map, BalancePaymentParam param, Map<String, String> commissionMap) {
//        //创建BigDecimal对象用来记录商户需要支付的总金额
//        final BigDecimal[] count = {new BigDecimal("0")};
//
//        //创建集合
//        List<AcctInfo> acctInfos = new ArrayList<>();
//
//        //遍历map集合
//        map.forEach((key, value) -> {
//            //创建AcctInfo对象
//            AcctInfo acctInfo = new AcctInfo();
//
//            //设置汇付id
//            acctInfo.setHuifuId(commissionMap.get("huifu_id" + key));
//
//            //计算分账金额并设置
//            value = value.subtract(value.multiply(new BigDecimal(commissionMap.get("commission" + key))));
//
//            //将金额小数点2位之后的舍掉
//            BigDecimal newVal = value.setScale(2, RoundingMode.DOWN);
//
//            acctInfo.setDivAmt(newVal.toString());
//
//            //累加汇总支付总金额
//            count[0] = count[0].add(newVal);
//
//            //将acctInfo放入集合
//            acctInfos.add(acctInfo);
//        });
//
//        //设置属性
//        param.setOrdAmt(count[0].toString());
//        param.setAcctInfos(acctInfos);
//    }
//
//    /**
//     * 根据租户id查询每个租户的手续费及租户对应的汇付id
//     */
//    private Map<String, String> getCommissionMap(Map<Long, BigDecimal> map) {
//        //创建Map集合
//        Map<String, String> commissionMap = new HashMap<>();
//
//        //获取所有租户id
//        ArrayList<Long> tenantIds = new ArrayList<>(map.keySet());
//
//        //根据租户id批量查询
//        List<EnterpriseUserMsg> enterpriseUserMsgList = enterpriseUserMsgMapper.selectList(new LambdaQueryWrapper<EnterpriseUserMsg>()
//                .in(EnterpriseUserMsg::getTenantId, tenantIds));
//
//        //安全校验
//        if (Objects.isNull(enterpriseUserMsgList) || enterpriseUserMsgList.size() < 1) {
//            return commissionMap;
//        }
//
//        //遍历集合
//        enterpriseUserMsgList.forEach(s -> {
//            commissionMap.put("commission" + s.getTenantId(), s.getCommission());
//            commissionMap.put("huifu_id" + s.getTenantId(), s.getHuifuId());
//        });
//
//        return commissionMap;
//    }
//
//    /**
//     * 遍历集合计算每个租户的订单总额，并将订单状态修改为已分账
//     */
//    private Map<Long, BigDecimal> countAndUpdate(List<PayOrder> orderList) {
//        //创建Map集合
//        Map<Long, BigDecimal> map = new HashMap<>();
//
//        //遍历集合
//        orderList.forEach(s -> {
//            //获取租户id
//            Long tenantId = s.getTenantId();
//            //获取当前订单的金额并转换为BigDecimal
//            BigDecimal transAmt = new BigDecimal(s.getTransAmt());
//            //判断当前集合中是否有该租户id
//            if (map.containsKey(tenantId)) {
//                //如果有直接将金额进行累加
//                map.put(tenantId, map.get(tenantId).add(transAmt));
//            } else {
//                //如果不存在则直接添加
//                map.put(tenantId, transAmt);
//            }
//        });
//
//        //返回结果
//        return map;
//    }
//
//
//    /**
//     * 遍历集合计算每个租户的订单总额，并将订单状态修改为已分账
//     */
//    private Map<Long, List<PayOrder>> payOrderMap(List<PayOrder> orderList) {
//        //创建Map集合
//        Map<Long, List<PayOrder>> map = new HashMap<>();
//
//        for (PayOrder cur : orderList) {
//            if (map.get(cur.getTenantId()) == null) {
//                map.put(cur.getTenantId(), new ArrayList<>());
//            }
//            map.get(cur.getTenantId()).add(cur);
//        }
//
//        //返回结果
//        return map;
//    }
//}
